package com.battcn.demo1;

import java.util.ArrayList;
import java.util.List;

interface Visitor {

    /**
     * 对应于NodeA的访问操作
     *
     * @param node node
     */
    void visit(NodeA node);

    /**
     * 对应于NodeB的访问操作
     *
     * @param node node
     */
    void visit(NodeB node);
}

class VisitorA implements Visitor {
    /**
     * 对应于NodeA的访问操作
     */
    @Override
    public void visit(NodeA node) {
        System.out.println(node.operationA());
    }

    /**
     * 对应于NodeB的访问操作
     */
    @Override
    public void visit(NodeB node) {
        System.out.println(node.operationB());
    }

}

class VisitorB implements Visitor {
    /**
     * 对应于NodeA的访问操作
     */
    @Override
    public void visit(NodeA node) {
        System.out.println(node.operationA());
    }

    /**
     * 对应于NodeB的访问操作
     */
    @Override
    public void visit(NodeB node) {
        System.out.println(node.operationB());
    }

}

interface Node {

    /**
     * 接受操作
     *
     * @param visitor 访问者对象
     */
    void accept(Visitor visitor);
}

class NodeA implements Node {

    /**
     * 接受操作
     */
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    /**
     * NodeA特有的方法
     */
    public String operationA() {
        return "NodeA";
    }
}

class NodeB implements Node {
    /**
     * 接受方法
     */
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    /**
     * NodeB特有的方法
     */
    public String operationB() {
        return "NodeB";
    }
}

class ObjectStructure {
    private List<Node> nodes = new ArrayList<>();

    /**
     * 执行方法操作
     */
    public void action(Visitor visitor) {
        for (Node node : nodes) {
            node.accept(visitor);
        }
    }

    /**
     * 添加一个新元素
     */
    public void add(Node node) {
        nodes.add(node);
    }
}

/**
 * @author Levin
 * @create 2017/12/19 0019
 */
public class Client {

    public static void main(String[] args) {
        //创建一个结构对象
        ObjectStructure os = new ObjectStructure();
        //给结构增加一个节点
        os.add(new NodeA());
        //给结构增加一个节点
        os.add(new NodeB());
        //创建一个访问者
        Visitor visitor = new VisitorA();
        os.action(visitor);
    }
}
